home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / PRI.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  31KB  |  1,488 lines

  1. /*    SCCS Id: @(#)pri.c    3.0    89/11/15
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #define MONATTK_H    /* comment line for pre-compiled headers */
  6. /* block some unused #defines to avoid overloading some cpp's */
  7. #include "hack.h"
  8. #if defined(ALTARS) && defined(THEOLOGY)
  9. #include "epri.h"
  10. #endif
  11. #include "termcap.h"
  12.  
  13. #ifdef OVL0
  14. static void FDECL(fillbot, (int,char *,char *));
  15. static void NDECL(bot1);
  16. static void NDECL(bot2);
  17. #endif /* OVL0 */
  18.  
  19. STATIC_DCL void FDECL(hilite, (int,int,UCHAR_P, UCHAR_P));
  20. STATIC_DCL void FDECL(cornbot, (int));
  21. #ifdef TEXTCOLOR
  22. STATIC_DCL uchar FDECL(mimic_color, (struct monst *));
  23. #endif
  24.  
  25. #ifdef OVL0
  26. # ifndef ASCIIGRAPH
  27. # define g_putch  (void) putchar
  28. # endif /* ASCIIGRAPH */
  29.  
  30. # ifndef g_putch
  31. static void FDECL(g_putch, (UCHAR_P));
  32. static boolean GFlag = FALSE; /* graphic flag */
  33. # endif
  34. #endif /* OVL0 */
  35.  
  36. /* 100 suffices for bot(); must be larger than COLNO */
  37. #define MAXCO 100
  38. STATIC_VAR char NEARDATA oldbot1[MAXCO], NEARDATA newbot1[MAXCO];
  39. STATIC_VAR char NEARDATA oldbot2[MAXCO], NEARDATA newbot2[MAXCO];
  40. #ifdef OVL2
  41. static const char NEARDATA *dispst = "*0#@#0#*0#@#0#*0#@#0#*0#@#0#*0#@#0#*";
  42. #endif /* OVL2 */
  43. #ifndef OVLB
  44. STATIC_DCL int mrank_sz;
  45. #else /* OVLB */
  46. STATIC_OVL int NEARDATA mrank_sz = 0;  /* loaded by max_rank_sz (called in u_init) */
  47. #endif /* OVLB */
  48.  
  49. #ifdef CLIPPING
  50. #define curs(x, y) (void) win_curs((x), (y)-2)
  51. #endif
  52.  
  53. #ifdef OVL0
  54.  
  55. char *
  56. eos(s)
  57. register char *s;
  58. {
  59.     while(*s) s++;
  60.     return(s);
  61. }
  62.  
  63. #endif /* OVL0 */
  64. #ifdef OVLB
  65.  
  66. void
  67. swallowed(first)
  68. register int first;
  69. {
  70.     if(first) cls();
  71.     else {
  72.         curs(u.ustuck->mdx-1, u.ustuck->mdy+1);
  73. #ifdef MACOS
  74.         puts("   ");
  75. #else
  76.         (void) fputs("   ", stdout);
  77. #endif
  78.         curx = u.ustuck->mdx+2;
  79.         curs(u.ustuck->mdx-1, u.ustuck->mdy+2);
  80. #ifdef MACOS
  81.         puts("   ");
  82. #else
  83.         (void) fputs("   ", stdout);
  84. #endif
  85.         curx = u.ustuck->mdx+2;
  86.         curs(u.ustuck->mdx-1, u.ustuck->mdy+3);
  87. #ifdef MACOS
  88.         puts("   ");
  89. #else
  90.         (void) fputs("   ", stdout);
  91. #endif
  92.         curx = u.ustuck->mdx+2;
  93.     }
  94.     curs(u.ux-1, u.uy+1);
  95. #ifdef MACOS
  96.     puts("/-\\");
  97. #else
  98.     (void) fputs("/-\\", stdout);
  99. #endif
  100.     curx = u.ux+2;
  101.     curs(u.ux-1, u.uy+2);
  102.     (void) putchar('|');
  103.     hilite(u.ux, u.uy, u.usym, AT_MON);
  104.     (void) putchar('|');
  105.     curx = u.ux+2;
  106.     curs(u.ux-1, u.uy+3);
  107. #ifdef MACOS
  108.     puts("\\-/");
  109. #else
  110.     (void) fputs("\\-/", stdout);
  111. #endif
  112.     curx = u.ux+2;
  113.     u.udispl = 1;
  114.     u.udisx = u.ux;
  115.     u.udisy = u.uy;
  116. }
  117. #ifdef CLIPPING
  118. #undef curs
  119. #endif
  120.  
  121. void
  122. setclipped()
  123. {
  124. #ifndef CLIPPING
  125.     error("NetHack needs a screen of size at least %d by %d.\n",
  126.         ROWNO+3, COLNO);
  127. #else
  128.     clipping = TRUE;
  129.     clipx = clipy = 0;
  130.     clipxmax = CO;
  131.     clipymax = LI - 3;
  132. #endif
  133. }
  134.  
  135. #endif /* OVLB */
  136. #ifdef OVL0
  137.  
  138. #ifdef CLIPPING
  139. void
  140. cliparound(x, y)
  141. int x, y;
  142. {
  143.     int oldx = clipx, oldy = clipy;
  144.  
  145.     if (!clipping) return;
  146.     if (x < clipx + 5) {
  147.         clipx = max(0, x - 20);
  148.         clipxmax = clipx + CO;
  149.     }
  150.     else if (x > clipxmax - 5) {
  151.         clipxmax = min(COLNO, clipxmax + 20);
  152.         clipx = clipxmax - CO;
  153.     }
  154.     if (y < clipy + 2) {
  155.         clipy = max(0, y - 10);
  156.         clipymax = clipy + (LI - 3);
  157.     }
  158.     else if (y > clipymax - 2) {
  159.         clipymax = min(ROWNO, clipymax + 10);
  160.         clipy = clipxmax - (LI - 3);
  161.     }
  162.     if (clipx != oldx || clipy != oldy) {
  163.         if (u.udispl) {
  164.             u.udispl = 0;
  165.             levl[u.udisx][u.udisy].scrsym = news0(u.udisx, u.udisy);
  166.         }
  167.         (void) doredraw();
  168.     }
  169. }
  170. #endif /* CLIPPING */
  171.  
  172. /*
  173.  *  Allow for a different implementation than this...
  174.  */
  175.  
  176. #ifndef g_putch
  177.  
  178. static void
  179. g_putch(ch)
  180. uchar ch;
  181. {
  182.     if (flags.IBMgraphics)
  183.         /* IBM-compatible displays don't need other stuff */
  184.         (void) putchar(ch);
  185.     else if (ch & 0x80) {
  186.         if (!GFlag) {
  187.             graph_on();
  188.             GFlag = TRUE;
  189.         }
  190.         (void) putchar(ch ^ 0x80); /* Strip 8th bit */
  191.     } else {
  192.         if (GFlag) {
  193.             graph_off();
  194.             GFlag = FALSE;
  195.         }
  196.         (void) putchar(ch);
  197.     }
  198. }
  199.  
  200. #endif
  201.  
  202. boolean
  203. showmon(mon)
  204. register struct monst *mon;
  205. {
  206.     register boolean show = (Blind && Telepat) || canseemon(mon);
  207.  
  208.     if (!show && (HTelepat & WORN_HELMET))
  209.         show = (dist(mon->mx, mon->my) <= (BOLT_LIM * BOLT_LIM));
  210.     return(show);
  211. }
  212.  
  213. void
  214. at(x,y,ch,typ)
  215. register xchar x,y;
  216. uchar ch,typ;
  217. {
  218. #ifndef LINT
  219.     /* if xchar is unsigned, lint will complain about  if(x < 0)  */
  220.     if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
  221.         impossible("At gets 0%o at %d %d.", ch, x, y);
  222.         return;
  223.     }
  224. #endif
  225.     if(!ch) {
  226.         impossible("At gets null at %d %d.", x, y);
  227.         return;
  228.     }
  229.  
  230.     if (typ == AT_APP
  231. #if !defined(MSDOS) && !defined(MACOS)
  232.         && flags.standout
  233. #endif
  234.        )
  235.         /* don't hilite if this isn't a monster or object.
  236.          *
  237.          * not complete; a scroll dropped by some monster
  238.          * on an unseen doorway which is later magic mapped
  239.          * will still hilite the doorway symbol.  -3.
  240.          */
  241.         if (!vism_at(x,y) &&
  242.             (!OBJ_AT(x, y) && !levl[x][y].gmask || is_pool(x,y)))
  243.             typ = AT_MAP;
  244.  
  245. #ifdef CLIPPING
  246.     if (win_curs(x, y)) {
  247. #else
  248.     curs(x,y+2);
  249. #endif
  250.     hilite(x, y, ch, typ);
  251.     curx++;
  252. #ifdef CLIPPING
  253.     }
  254. #endif
  255. }
  256.  
  257. #endif /* OVL0 */
  258. #ifdef OVLB
  259.  
  260. void
  261. prme(){
  262.     if(!Invisible
  263. #ifdef POLYSELF
  264.             && !u.uundetected
  265. #endif
  266.                     ) {
  267.         levl[u.ux][u.uy].seen = 0; /* force atl */
  268.         atl(u.ux,u.uy,(char)u.usym);
  269.     }
  270. }
  271.  
  272. #endif /* OVLB */
  273. #ifdef OVL2
  274.  
  275. void
  276. shieldeff(x, y)        /* produce a magical shield effect at x,y */
  277.     register xchar x, y;
  278. {
  279.     register const char *ch;
  280.     register struct monst *mtmp = 0;
  281.  
  282.     nscr();
  283.  
  284.     if((x == u.ux) && (y == u.uy)) 
  285.         curs_on_u();
  286.     else {
  287.         if(!(mtmp = m_at(x, y))) {
  288.  
  289.         impossible("shield effect at %d,%d", x, y);
  290.         return;
  291.         }
  292.         if(!showmon(mtmp)) return;
  293.     }
  294.  
  295.     for(ch = dispst; *ch; ch++)  {
  296.         at(x, y, (uchar) *ch, AT_ZAP);
  297.         (void) fflush(stdout);
  298.         delay_output();
  299.         delay_output();
  300.     }
  301.  
  302.     nomul(0);
  303.     if(!mtmp) {
  304.         if(Invisible) {
  305.             prl(x, y);
  306.             at(x, y, levl[x][y].scrsym, AT_APP);
  307.         } else prme();
  308.     } else {
  309.         mtmp->mdispl = 0;    /* make sure it gets redrawn */
  310.         prl(x, y);
  311.         if(mtmp->minvis)
  312.             at(x, y, levl[x][y].scrsym, AT_APP);
  313.         else    at(x, y, (uchar) mtmp->data->mlet, AT_MON);
  314.     }
  315.  
  316.     return;
  317. }
  318.  
  319. #endif /* OVL2 */
  320. #ifdef OVLB
  321.  
  322. int
  323. doredraw()
  324. {
  325.     docrt();
  326.     return 0;
  327. }
  328.  
  329. #endif /* OVLB */
  330. #ifdef OVL0
  331.  
  332. void
  333. docrt()
  334. {
  335.     register int x,y;
  336.     register struct rm *room;
  337.     register struct monst *mtmp;
  338. #ifdef MACOS
  339.     term_info    *t;
  340.     extern WindowPtr HackWindow;
  341. #endif
  342.  
  343.     if(u.uswallow) {
  344.         swallowed(1);
  345.         return;
  346.     }
  347.     cls();
  348.  
  349. /* Some ridiculous code to get display of @ and monsters (almost) right */
  350.     if(!Invisible
  351. #ifdef POLYSELF
  352.             && !u.uundetected
  353. #endif
  354.                     ) {
  355.         u.udisx = u.ux;
  356.         u.udisy = u.uy;
  357.         levl[u.udisx][u.udisy].scrsym = u.usym;
  358.         levl[u.udisx][u.udisy].seen = 1;
  359.         u.udispl = 1;
  360.     } else    u.udispl = 0;
  361.  
  362.     seemons();    /* reset old positions */
  363.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  364.         mtmp->mdispl = 0;
  365.     seemons();    /* force new positions to be shown */
  366.  
  367. #if ((defined(DGK) && !defined(TEXTCOLOR)) || defined(MACOS)) && !defined(CLIPPING)
  368. # ifdef MACOS
  369.     t = (term_info *)GetWRefCon(HackWindow);
  370.     if (!t->inColor)
  371. # endif
  372.     /* Otherwise, line buffer the output to do the redraw in
  373.      * about 2/3 of the time.
  374.      */
  375.         for(y = 0; y < ROWNO; y++) {
  376.             char buf[COLNO+1];
  377.             int start, end;
  378. # if defined(LSC) || defined(AZTEC) || defined(AZTEC_C)
  379.             setmem(buf, COLNO, ' ');
  380. # else
  381.             memset(buf, ' ', COLNO);
  382. # endif
  383.             for(x = 0, start = -1, end = -1; x < COLNO; x++)
  384.                 if((room = &levl[x][y])->new) {
  385.                     room->new = 0;
  386.                     buf[x] = room->scrsym;
  387.                     if (start < 0)
  388.                         start = x;
  389.                     end = x;
  390.                 } else if(room->seen) {
  391.                     buf[x] = room->scrsym;
  392.                     if (start < 0)
  393.                         start = x;
  394.                     end = x;
  395.                 }
  396.             if (end >= 0) {
  397.                 buf[end + 1] = '\0';
  398.                 curs(start, y + 2);
  399. # ifdef MACOS
  400.                 puts(buf + start);
  401. # else
  402.                 (void) fputs(buf + start, stdout);
  403. # endif
  404.                 curx = end + 1;
  405.             }
  406.         }
  407. # ifdef MACOS
  408.     else {
  409.         for(y = 0; y < ROWNO; y++)
  410.         for(x = 0; x < COLNO; x++)
  411.             if((room = &levl[x][y])->new) {
  412.                 room->new = 0;
  413.                 at(x,y,room->scrsym,AT_APP);
  414.             } else if(room->seen)
  415.                 at(x,y,room->scrsym,AT_APP);
  416.     }
  417. # endif
  418. #else
  419.     for(y = 0; y < ROWNO; y++)
  420.         for(x = 0; x < COLNO; x++)
  421.             if((room = &levl[x][y])->new) {
  422.                 room->new = 0;
  423.                 at(x,y,room->scrsym,AT_APP);
  424.             } else if(room->seen)
  425.                 at(x,y,room->scrsym,AT_APP);
  426. #endif /* DGK && !TEXTCOLOR && !CLIPPING */
  427. #ifndef g_putch
  428.     if (GFlag) {
  429.         graph_off();
  430.         GFlag = FALSE;
  431.     }
  432. #endif
  433.     scrlx = COLNO;
  434.     scrly = ROWNO;
  435.     scrhx = scrhy = 0;
  436.     cornbot(0);
  437.     bot();
  438. }
  439.  
  440. #endif /* OVL0 */
  441. #ifdef OVLB
  442.  
  443. STATIC_OVL void
  444. cornbot(lth)
  445. register int lth;
  446. {
  447.     oldbot1[lth] = 0;
  448.     oldbot2[lth] = 0;
  449.     flags.botl = 1;
  450. }
  451.  
  452. #endif /* OVLB */
  453. #ifdef OVL0
  454.  
  455. void
  456. docorner(xmin, ymax)
  457. register int xmin, ymax;
  458. {
  459.     register int x, y;
  460.     register struct rm *room;
  461.     register struct monst *mtmp;
  462.  
  463.     if(u.uswallow) {    /* Can be done more efficiently */
  464.         swallowed(1);
  465.         return;
  466.     }
  467.  
  468. #ifdef CLIPPING
  469.     xmin += clipx; ymax += clipy;
  470. #endif
  471.     seemons();    /* reset old positions */
  472.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  473.         if(mtmp->mx >= xmin && mtmp->my < ymax)
  474.         mtmp->mdispl = 0;
  475.     seemons();    /* force new positions to be shown */
  476.  
  477. #ifdef CLIPPING
  478.     for(y = clipy; y < ymax; y++) {
  479.         if(clipping && y > clipymax && CD) break;
  480.         curs(xmin - clipx, (y - clipy)+2);
  481. #else
  482.     for(y = 0; y < ymax; y++) {
  483.         if(y > ROWNO+1 && CD) break;
  484.         curs(xmin,y+2);
  485. #endif
  486.         cl_end();
  487.         if(y < ROWNO) {
  488.             for(x = xmin; x < COLNO; x++) {
  489.             if((room = &levl[x][y])->new) {
  490.                 room->new = 0;
  491.                 at(x,y,room->scrsym,AT_APP);
  492.             } else
  493.                 if(room->seen)
  494.                     at(x,y,room->scrsym,AT_APP);
  495.             }
  496.         }
  497.     }
  498. #ifndef g_putch
  499.     if (GFlag) {
  500.         graph_off();
  501.         GFlag = FALSE;
  502.     }
  503. #endif
  504.     /* Note:          y values: 0 to ymax-1
  505.      * screen positions from y: 2 to ymax+1
  506.      *            whole screen: 1 to ROWNO+3
  507.      *                top line: 1
  508.      *         dungeon display: 2 to ROWNO+1
  509.      *       first bottom line: ROWNO+2
  510.      *      second bottom line: ROWNO+3
  511.      *         lines on screen: ROWNO+3
  512.      */
  513.     if(ymax > ROWNO) {
  514.         cornbot(xmin-1);
  515.         if(ymax > ROWNO+2 && CD) {    /* clear portion of long */
  516.             curs(1,ROWNO+4);    /* screen below status lines */
  517.             cl_eos();
  518.         }
  519.     }
  520. }
  521.  
  522. #endif /* OVL0 */
  523. #ifdef OVL1
  524.  
  525. void
  526. seeglds()
  527. {
  528.     register struct gold *gold, *gold2;
  529.  
  530.     for(gold = fgold; gold; gold = gold2) {
  531.         gold2 = gold->ngold;
  532.         if(Hallucination && cansee(gold->gx,gold->gy))
  533.         if(!(gold->gx == u.ux && gold->gy == u.uy) || Invisible)
  534.             atl(gold->gx,gold->gy,rndobjsym());
  535.     }
  536. }
  537.  
  538. /* Trolls now regenerate thanks to KAA */
  539.  
  540. void
  541. seeobjs()
  542. {
  543.     register struct obj *obj, *obj2;
  544.  
  545.     for(obj = fobj; obj; obj = obj2) {
  546.         obj2 = obj->nobj;
  547.  
  548.         if(Hallucination && cansee(obj->ox,obj->oy))
  549.         if(!(obj->ox == u.ux && obj->oy == u.uy) || Invisible)
  550.             atl(obj->ox,obj->oy,rndobjsym());
  551.  
  552.         if(obj->olet == FOOD_SYM && obj->otyp == CORPSE) {
  553.  
  554.         if(mons[obj->corpsenm].mlet == S_TROLL &&
  555.             obj->age + 20 < monstermoves) {
  556.             boolean visible = cansee(obj->ox,obj->oy);
  557.             struct monst *mtmp = revive(obj, FALSE);
  558.  
  559.             if (mtmp && visible)
  560.                 pline("%s rises from the dead!",
  561.                     (mtmp->mhp==mtmp->mhpmax) ? Monnam(mtmp)
  562.                     : Amonnam(mtmp, "bite-covered"));
  563.         } else if (obj->corpsenm != PM_LIZARD &&
  564.                         obj->age + 250 < monstermoves)
  565.             delobj(obj);
  566.         }
  567.     }
  568.  
  569.     for(obj = invent; obj; obj = obj2) {
  570.         obj2 = obj->nobj;
  571.         if(obj->otyp == CORPSE) {
  572.         if(mons[obj->corpsenm].mlet == S_TROLL
  573.                 && obj->age + 20 < monstermoves) {
  574.             boolean wielded = (obj==uwep);
  575.             struct monst *mtmp = revive(obj, TRUE);
  576.  
  577.             if (mtmp && wielded)
  578.             pline("The %s%s %s writhes out of your grasp!",
  579.                 (mtmp->mhp < mtmp->mhpmax) ? "bite-covered ":"",
  580.                 mtmp->data->mname, xname(obj));
  581.             else if (mtmp)
  582.             You("feel squirming in your backpack!");
  583.         } else if (obj->corpsenm != PM_LIZARD &&
  584.                         obj->age + 250 < monstermoves)
  585.             useup(obj);
  586.         }
  587.     }
  588. }
  589.  
  590. #endif /* OVL1 */
  591. #ifdef OVL0
  592.  
  593. void
  594. seemons()
  595. {
  596.     register struct monst *mtmp;
  597.  
  598.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  599.         if(mtmp->data->mlet == S_EEL)
  600.         mtmp->minvis = (u.ustuck != mtmp && is_pool(mtmp->mx,mtmp->my));
  601.         pmon(mtmp);
  602. #ifdef WORM
  603.         if(mtmp->wormno) wormsee(mtmp->wormno);
  604. #endif
  605.     }
  606. }
  607.  
  608. void
  609. pmon(mon)
  610. register struct monst *mon;
  611. {
  612.     register int show = showmon(mon);
  613.  
  614.     if(mon->mdispl)
  615.         if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
  616.         unpmon(mon);
  617.  
  618. /* If you're hallucinating, the monster must be redrawn even if it has
  619.  * already been printed.
  620.  */
  621.     if(show && (!mon->mdispl || Hallucination)) {
  622.         if (Hallucination)
  623.         atl(mon->mx,mon->my,
  624.         (char) ((!mon->mimic || Protection_from_shape_changers) ?
  625.         rndmonsym() : (mon->m_ap_type == M_AP_FURNITURE) ?
  626.         showsyms[mon->mappearance] : rndobjsym()));
  627.         else
  628.  
  629.         atl(mon->mx,mon->my,
  630.             (!mon->m_ap_type ||
  631.              Protection_from_shape_changers) ?
  632.              mon->data->mlet : (char) mimic_appearance(mon));
  633.         mon->mdispl = 1;
  634.         mon->mdx = mon->mx;
  635.         mon->mdy = mon->my;
  636.     }
  637. #ifndef g_putch
  638.     if (GFlag) {
  639.         graph_off();
  640.         GFlag = FALSE;
  641.     }
  642. #endif
  643. }
  644.  
  645. #endif /* OVL0 */
  646. #ifdef OVL1
  647.  
  648. void
  649. unpmon(mon)
  650. register struct monst *mon;
  651. {
  652.     if(mon->mdispl) {
  653.         newsym(mon->mdx, mon->mdy);
  654.         mon->mdispl = 0;
  655.     }
  656. }
  657.  
  658. #endif /* OVL1 */
  659. #ifdef OVL0
  660.  
  661. void
  662. nscr() {
  663.     register int x, y;
  664.     register struct rm *room;
  665.  
  666.     if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
  667.     pru();
  668.     for(y = scrly; y <= scrhy; y++)
  669.         for(x = scrlx; x <= scrhx; x++)
  670.             if((room = &levl[x][y])->new) {
  671.                 room->new = 0;
  672.                 at(x,y,room->scrsym,AT_APP);
  673.             }
  674. #ifndef g_putch
  675.     if (GFlag) {
  676.         graph_off();
  677.         GFlag = FALSE;
  678.     }
  679. #endif
  680.     scrhx = scrhy = 0;
  681.     scrlx = COLNO;
  682.     scrly = ROWNO;
  683. }
  684.  
  685. #endif /* OVL0 */
  686. #ifdef OVL1
  687.  
  688. /* Make sure that there are 18 entries in the rank arrays. */
  689. /* 0 and even entries are male ranks, odd entries are female. */
  690.  
  691. static const char NEARDATA *mage_ranks[] = {
  692.     "Evoker",
  693.     "Evoker",
  694.     "Conjurer",
  695.     "Conjurer",
  696.     "Thaumaturge",
  697.     "Thaumaturge",
  698.     "Magician",
  699.     "Magician",
  700.     "Enchanter",
  701.     "Enchanter",
  702.     "Sorcerer",
  703.     "Sorceress",
  704.     "Necromancer",
  705.     "Necromancer",
  706.     "Wizard",
  707.     "Wizard",
  708.     "Mage",
  709.     "Mage"
  710. };
  711.  
  712. static const char NEARDATA *priest_ranks[] = {
  713.     "Aspirant",
  714.     "Aspirant",
  715.     "Acolyte",
  716.     "Acolyte",
  717.     "Adept",
  718.     "Adept",
  719.     "Priest",
  720.     "Priestess",
  721.     "Curate",
  722.     "Curate",
  723.     "Canon",
  724.     "Canoness",
  725.     "Lama",
  726.     "Lama",
  727.     "Patriarch",
  728.     "Matriarch",
  729.     "High Priest",
  730.     "High Priestess"
  731. };
  732.  
  733. static const char NEARDATA *thief_ranks[] = {
  734.     "Footpad",
  735.     "Footpad",
  736.     "Cutpurse",
  737.     "Cutpurse",
  738.     "Rogue",
  739.     "Rogue",
  740.     "Pilferer",
  741.     "Pilferer",
  742.     "Robber",
  743.     "Robber",
  744.     "Burglar",
  745.     "Burglar",
  746.     "Filcher",
  747.     "Filcher",
  748.     "Magsman",
  749.     "Magswoman",
  750.     "Thief",
  751.     "Thief"
  752. };
  753.  
  754. static const char NEARDATA *fighter_ranks[] = {
  755.     "Stripling",
  756.     "Stripling",
  757.     "Skirmisher",
  758.     "Skirmisher",
  759.     "Fighter",
  760.     "Fighter",
  761.     "Man-at-arms",
  762.     "Woman-at-arms",
  763.     "Warrior",
  764.     "Warrior",
  765.     "Swashbuckler",
  766.     "Swashbuckler",
  767.     "Hero",
  768.     "Heroine",
  769.     "Champion",
  770.     "Champion",
  771.     "Lord",
  772.     "Lady"
  773. };
  774.  
  775. static const char NEARDATA *tourist_ranks[] = {
  776.     "Rambler",
  777.     "Rambler",
  778.     "Sightseer",
  779.     "Sightseer",
  780.     "Excursionist",
  781.     "Excursionist",
  782.     "Peregrinator",
  783.     "Peregrinator",
  784.     "Traveler",
  785.     "Traveler",
  786.     "Journeyer",
  787.     "Journeyer",
  788.     "Voyager",
  789.     "Voyager",
  790.     "Explorer",
  791.     "Explorer",
  792.     "Adventurer",
  793.     "Adventurer"
  794. };
  795.  
  796. static const char NEARDATA *nomad_ranks[] = {
  797.     "Troglodyte",
  798.     "Troglodyte",
  799.     "Aborigine",
  800.     "Aborigine",
  801.     "Wanderer",
  802.     "Wanderer",
  803.     "Vagrant",
  804.     "Vagrant",
  805.     "Wayfarer",
  806.     "Wayfarer",
  807.     "Roamer",
  808.     "Roamer",
  809.     "Nomad",
  810.     "Nomad",
  811.     "Rover",
  812.     "Rover",
  813.     "Pioneer",
  814.     "Pioneer"
  815. };
  816.  
  817. static const char NEARDATA *knight_ranks[] = {
  818.     "Gallant",
  819.     "Gallant",
  820.     "Esquire",
  821.     "Esquire",
  822.     "Bachelor",
  823.     "Bachelor",
  824.     "Sergeant",
  825.     "Sergeant",
  826.     "Knight",
  827.     "Knight",
  828.     "Banneret",
  829.     "Banneret",
  830.     "Chevalier",
  831.     "Chevalier",
  832.     "Seignieur",
  833.     "Seignieur",
  834.     "Paladin",
  835.     "Paladin"
  836. };
  837.  
  838. static const char NEARDATA *archeo_ranks[] = {
  839.     "Digger",
  840.     "Digger",
  841.     "Field Worker",
  842.     "Field Worker",
  843.     "Investigator",
  844.     "Investigator",
  845.     "Exhumer",
  846.     "Exhumer",
  847.     "Excavator",
  848.     "Excavator",
  849.     "Spelunker",
  850.     "Spelunker",
  851.     "Speleologist",
  852.     "Speleologist",
  853.     "Collector",
  854.     "Collector",
  855.     "Curator",
  856.     "Curator"
  857. };
  858.  
  859. static const char NEARDATA *healer_ranks[] = {
  860.     "Pre-Med",
  861.     "Pre-Med",
  862.     "Med Student",
  863.     "Med Student",
  864.     "Medic",
  865.     "Medic",
  866.     "Intern",
  867.     "Intern",
  868.     "Doctor",
  869.     "Doctor",
  870.     "Physician",
  871.     "Physician",
  872.     "Specialist",
  873.     "Specialist",
  874.     "Surgeon",
  875.     "Surgeon",
  876.     "Chief Surgeon",
  877.     "Chief Surgeon"
  878. };
  879.  
  880. static const char NEARDATA *barbarian_ranks[] = {
  881.     "Plunderer",
  882.     "Plunderess",
  883.     "Pillager",
  884.     "Pillager",
  885.     "Bandit",
  886.     "Bandit",
  887.     "Brigand",
  888.     "Brigand",
  889.     "Raider",
  890.     "Raider",
  891.     "Reaver",
  892.     "Reaver",
  893.     "Slayer",
  894.     "Slayer",
  895.     "Chieftain",
  896.     "Chieftainess",
  897.     "Conqueror",
  898.     "Conqueress"
  899. };
  900.  
  901. static const char NEARDATA *ninja_ranks[] = {
  902.     "Chigo",
  903.     "Chigo",
  904.     "Bushi",
  905.     "Bushi",
  906.     "Genin",
  907.     "Genin",
  908.     "Genin",
  909.     "Genin",
  910.     "Chunin",
  911.     "Chunin",
  912.     "Chunin",
  913.     "Chunin",
  914.     "Jonin",
  915.     "Jonin",
  916.     "Jonin",
  917.     "Jonin",
  918.     "Jonin",
  919.     "Jonin",
  920. };
  921.  
  922. static const char NEARDATA *elf_ranks[] = {
  923.     "Edhel",
  924.     "Elleth",
  925.     "Edhel",
  926.     "Elleth",     /* elf-maid */
  927.     "Ohtar",     /* warrior */
  928.     "Ohtie",
  929.     "Kano",     /* commander (Q.) ['a] */
  930.     "Kanie",     /* educated guess, until further research- SAC */
  931.     "Arandur",     /* king's servant, minister (Q.) - educated guess */
  932.     "Aranduriel",     /* educated guess */
  933.     "Hir",         /* lord (S.) */
  934.     "Hiril",     /* lady (S.) ['ir] */
  935.     "Aredhel",     /* noble elf (S.) */
  936.     "Arwen",     /* noble maiden (S.) */
  937.     "Ernil",     /* prince (S.) */
  938.     "Elentariel",     /* elf-maiden (Q.) */
  939.     "Elentar",     /* Star-king (Q.) */
  940.     "Elentari",     /* Star-queen (Q.) */ /* Elbereth (S.) */
  941. };
  942.  
  943. #endif /* OVL1 */
  944.  
  945. STATIC_DCL const char **NDECL(rank_array);
  946.  
  947. #ifdef OVL1
  948.  
  949. STATIC_OVL const char **
  950. rank_array() {
  951.     register const char **ranks;
  952.  
  953.     switch(pl_character[0]) {
  954.         case 'A':  ranks = archeo_ranks; break;
  955.         case 'B':  ranks = barbarian_ranks; break;
  956.         case 'C':  ranks = nomad_ranks; break;
  957.         case 'E':  ranks = elf_ranks; break;
  958.         case 'H':  ranks = healer_ranks; break;
  959.         case 'K':  ranks = knight_ranks; break;
  960.         case 'P':  ranks = priest_ranks; break;
  961.         case 'R':  ranks = thief_ranks; break;
  962.         case 'S':  ranks = ninja_ranks; break;
  963.         case 'T':  ranks = tourist_ranks; break;
  964.         case 'V':  ranks = fighter_ranks; break;
  965.         case 'W':  ranks = mage_ranks; break;
  966.         default:   ranks = 0; break;
  967.     }
  968.     return(ranks);
  969. }
  970.  
  971. #endif /* OVL1 */
  972.  
  973. STATIC_DCL const char *NDECL(rank);
  974.  
  975. #ifdef OVL1
  976.  
  977. STATIC_OVL const char *
  978. rank() {
  979.     register int place;
  980.     register const char **ranks = rank_array();
  981.  
  982.     if(u.ulevel < 3) place = 0;
  983.     else if(u.ulevel <  6) place =  2;
  984.     else if(u.ulevel < 10) place =  4;
  985.     else if(u.ulevel < 14) place =  6;
  986.     else if(u.ulevel < 18) place =  8;
  987.     else if(u.ulevel < 22) place = 10;
  988.     else if(u.ulevel < 26) place = 12;
  989.     else if(u.ulevel < 30) place = 14;
  990.     else place = 16;
  991.     if(flags.female) place++;
  992.  
  993.     if (!!ranks) return(ranks[place]);
  994.     return(pl_character);
  995. }
  996.  
  997. #endif /* OVL1 */
  998. #ifdef OVLB
  999.  
  1000. void
  1001. max_rank_sz() {
  1002.     register int i, maxr = 0;
  1003.     register const char **ranks = rank_array();
  1004.  
  1005.     if (!!ranks) {
  1006.         for(i = flags.female; i < 18; i += 2)
  1007.             if(strlen(ranks[i]) > maxr) maxr = strlen(ranks[i]);
  1008.         mrank_sz = maxr;
  1009.     }
  1010.     else mrank_sz = strlen(pl_character);
  1011. }
  1012.  
  1013. #endif /* OVLB */
  1014. #ifdef OVL0
  1015.  
  1016. static void
  1017. fillbot(row,oldbot,newbot)
  1018. int row;
  1019. char *oldbot, *newbot;
  1020. {
  1021.     register char *ob = oldbot, *nb = newbot;
  1022.     register int i;
  1023.     int fillcol;
  1024.  
  1025.     fillcol = min(CO, MAXCO-1);
  1026.  
  1027.     /* compress in case line too long */
  1028.     if(strlen(newbot) >= fillcol) {
  1029.         register char *bp0 = newbot, *bp1 = newbot;
  1030.  
  1031.         do {
  1032. #ifdef CLIPPING
  1033.             if(*bp0 != ' ' || bp0[1] != ' ')
  1034. #else
  1035.             if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
  1036. #endif
  1037.                 *bp1++ = *bp0;
  1038.         } while(*bp0++);
  1039.     }
  1040.     newbot[fillcol] = '\0';
  1041.  
  1042.     for(i = 1; i < fillcol; i++) {
  1043.         if(!*nb) {
  1044.             if(*ob || flags.botlx) {
  1045.                 /* last char printed may be in middle of line */
  1046.                 curs((int)strlen(newbot)+1,row);
  1047.                 cl_end();
  1048.             }
  1049.             break;
  1050.         }
  1051.         if(*ob != *nb) {
  1052.             curs(i,row);
  1053.             (void) putchar(*nb);
  1054.             curx++;
  1055.         }
  1056.         if(*ob) ob++;
  1057.         nb++;
  1058.     }
  1059.     Strcpy(oldbot, newbot);
  1060. }
  1061.  
  1062. static void
  1063. bot1()
  1064. {
  1065.     register int i,j;
  1066.  
  1067. #ifdef CLIPPING
  1068.     if (CO > 59) {
  1069. #endif
  1070.     Strcpy(newbot1, plname);
  1071.     if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
  1072.     newbot1[10] = 0;
  1073.     Sprintf(eos(newbot1)," the ");
  1074. #ifdef POLYSELF
  1075.     if (u.mtimedone) {
  1076.         char mbot[BUFSZ];
  1077.         int k = 0;
  1078.  
  1079.         Strcpy(mbot, mons[u.umonnum].mname);
  1080.         while(mbot[k] != 0) {
  1081.             if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
  1082.                     'a' <= mbot[k] && mbot[k] <= 'z')
  1083.             mbot[k] += 'A' - 'a';
  1084.             k++;
  1085.         }
  1086.         Sprintf(eos(newbot1), mbot);
  1087.     } else
  1088.         Sprintf(eos(newbot1), rank());
  1089. #else
  1090.     Sprintf(eos(newbot1), rank());
  1091. #endif
  1092.     Sprintf(eos(newbot1),"  ");
  1093.     i = mrank_sz + 15;
  1094.     j = strlen(newbot1);
  1095.     if((i - j) > 0)
  1096.           do { Sprintf(eos(newbot1)," "); /* pad with spaces */
  1097.            i--;
  1098.           } while((i - j) > 0);
  1099. #ifdef CLIPPING
  1100.     }
  1101.     else
  1102.         *newbot1 = 0;
  1103. #endif
  1104.     if(ACURR(A_STR)>18) {
  1105.         if(ACURR(A_STR)>118)
  1106.             Sprintf(eos(newbot1),"St:%2d ",ACURR(A_STR)-100);
  1107.         else if(ACURR(A_STR)<118)
  1108.             Sprintf(eos(newbot1), "St:18/%02d ",ACURR(A_STR)-18);
  1109.         else
  1110.             Sprintf(eos(newbot1),"St:18/** ");
  1111.     } else
  1112.         Sprintf(eos(newbot1), "St:%-1d ",ACURR(A_STR));
  1113.     Sprintf(eos(newbot1),
  1114.         "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
  1115.         ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
  1116.     Sprintf(eos(newbot1), (u.ualigntyp == U_CHAOTIC) ? "  Chaotic" :
  1117.             (u.ualigntyp == U_NEUTRAL) ? "  Neutral" : "  Lawful");
  1118. #ifdef SCORE_ON_BOTL
  1119.     Sprintf(eos(newbot1)," S:%lu"
  1120.         ,(u.ugold - u.ugold0 > 0 ? u.ugold - u.ugold0 : 0)
  1121.         + u.urexp + (50 * maxdlevel)
  1122.         + (maxdlevel > 20? 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20) :0));
  1123. #endif
  1124. #ifdef CLIPPING
  1125.     fillbot(min(LI-1, ROWNO+2), oldbot1, newbot1);
  1126. #else
  1127.     fillbot(ROWNO+2, oldbot1, newbot1);
  1128. #endif
  1129. }
  1130.  
  1131. static void
  1132. bot2()
  1133. {
  1134. #ifdef ENDGAME
  1135.     if(dlevel == ENDLEVEL)
  1136.         Sprintf(newbot2, "EndLevel ");
  1137.     else
  1138. #endif
  1139. #ifdef SPELLS
  1140.         Sprintf(newbot2, "Dlvl:%-2d ", dlevel);
  1141. #else
  1142.         Sprintf(newbot2, "Level:%-1d ", dlevel);
  1143. #endif
  1144.     Sprintf(eos(newbot2),
  1145. #ifdef SPELLS
  1146.         "G:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d",
  1147.         u.ugold,
  1148. # ifdef POLYSELF
  1149.         u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
  1150.         u.uen, u.uenmax, u.uac);
  1151. # else
  1152.         u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
  1153. # endif
  1154. #else
  1155.         "Gold:%-1lu HP:%d(%d) AC:%-1d",
  1156.         u.ugold,
  1157. # ifdef POLYSELF
  1158.         u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
  1159.         u.uac);
  1160. # else
  1161.         u.uhp, u.uhpmax, u.uac);
  1162. # endif
  1163. #endif
  1164. #ifdef POLYSELF
  1165.     if (u.mtimedone)
  1166.         Sprintf(eos(newbot2), " HD:%d", mons[u.umonnum].mlevel);
  1167.     else
  1168. #endif
  1169. #ifdef EXP_ON_BOTL
  1170.     Sprintf(eos(newbot2), " Xp:%u/%-1ld", u.ulevel,u.uexp);
  1171. #else
  1172.     Sprintf(eos(newbot2), " Exp:%u", u.ulevel);
  1173. #endif
  1174.     if(flags.time)
  1175.         Sprintf(eos(newbot2), " T:%ld", moves);
  1176.     if(strcmp(hu_stat[u.uhs], "        ")) {
  1177.         Sprintf(eos(newbot2), " ");
  1178.         Strcat(newbot2, hu_stat[u.uhs]);
  1179.     }
  1180.     if(Confusion)       Sprintf(eos(newbot2), " Conf");
  1181.     if(Sick)       Sprintf(eos(newbot2), " Sick");
  1182.     if(Blind)       Sprintf(eos(newbot2), " Blind");
  1183.     if(Stunned)       Sprintf(eos(newbot2), " Stun");
  1184.     if(Hallucination)  Sprintf(eos(newbot2), " Hallu");
  1185. #ifdef CLIPPING
  1186.     fillbot(min(LI, ROWNO+3), oldbot2, newbot2);
  1187. #else
  1188.     fillbot(ROWNO+3, oldbot2, newbot2);
  1189. #endif
  1190. }
  1191.  
  1192. void
  1193. bot() {
  1194. register char *ob1 = oldbot1, *ob2 = oldbot2;
  1195.     if(flags.botlx) *ob1 = *ob2 = 0;
  1196.     bot1();
  1197.     bot2();
  1198.     flags.botl = flags.botlx = 0;
  1199. }
  1200.  
  1201. #endif /* OVL0 */
  1202. #ifdef OVLB
  1203.  
  1204. void
  1205. mstatusline(mtmp)
  1206. register struct monst *mtmp;
  1207. {
  1208. #if defined(ALTARS) && defined(THEOLOGY)
  1209.     int align = mtmp->ispriest
  1210.         ? ((EPRI(mtmp)->shralign & ~A_SHRINE)-1) :
  1211.         mtmp->data->maligntyp;
  1212. #else
  1213.     int align = mtmp->data->maligntyp;
  1214. #endif
  1215.     pline("Status of %s (%s): ", mon_nam(mtmp),
  1216.         (align <= -1) ? "chaotic" :
  1217.         align ? "lawful" : "neutral");
  1218.     pline("Level %d  Gold %lu  HP %d(%d)",
  1219.         mtmp->m_lev, mtmp->mgold, mtmp->mhp, mtmp->mhpmax);
  1220.     pline("AC %d%s%s", mtmp->data->ac,
  1221.         mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? ", tame" : "");
  1222. }
  1223.  
  1224. void
  1225. ustatusline()
  1226. {
  1227.     pline("Status of %s (%s%s):", plname,
  1228.         (u.ualign > 3) ? "stridently " :
  1229.         (u.ualign == 3) ? "" :
  1230.         (u.ualign >= 1) ? "haltingly " :
  1231.         (u.ualign == 0) ? "nominally " :
  1232.                 "insufficiently ",
  1233.         (u.ualigntyp == U_CHAOTIC) ? "chaotic" :
  1234.         u.ualigntyp ? "lawful" : "neutral");
  1235.     pline("Level %d  Gold %lu  HP %d(%d)  AC %d",
  1236. # ifdef POLYSELF
  1237.         u.mtimedone ? mons[u.umonnum].mlevel : u.ulevel,
  1238.         u.ugold, u.mtimedone ? u.mh : u.uhp,
  1239.         u.mtimedone ? u.mhmax : u.uhpmax, u.uac);
  1240. # else
  1241.         u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac);
  1242. # endif
  1243. }
  1244.  
  1245. void
  1246. cls()
  1247. {
  1248.     extern xchar tlx, tly;
  1249.  
  1250.     if(flags.toplin == 1)
  1251.         more();
  1252.     flags.toplin = 0;
  1253.  
  1254.     clear_screen();
  1255.  
  1256.     tlx = tly = 1;
  1257.  
  1258.     flags.botlx = 1;
  1259. }
  1260.  
  1261. #endif /* OVLB */
  1262. #ifdef OVL2
  1263.  
  1264. char
  1265. rndmonsym()
  1266. {
  1267.     return(mons[rn2(NUMMONS - 1)].mlet);
  1268. }
  1269.  
  1270. /*
  1271.  * we don't use objsyms here because (someday) objsyms may be
  1272.  * user programmable
  1273.  */
  1274.  
  1275. static const char NEARDATA rndobs[] = {
  1276.     WEAPON_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM,
  1277. #ifdef SPELLS
  1278.     SPBOOK_SYM,
  1279. #endif
  1280.     RING_SYM, AMULET_SYM, FOOD_SYM, TOOL_SYM, GEM_SYM, GOLD_SYM, ROCK_SYM };
  1281.  
  1282. char
  1283. rndobjsym()
  1284. {
  1285.     return rndobs[rn2(SIZE(rndobs))];
  1286. }
  1287.  
  1288. static const char NEARDATA *hcolors[] = {
  1289.             "ultraviolet", "infrared", "hot pink", "psychedelic",
  1290.             "bluish-orange", "reddish-green", "dark white",
  1291.             "light black", "loud", "salty", "sweet", "sour",
  1292.             "bitter", "luminescent", "striped", "polka-dotted",
  1293.             "square", "round", "triangular", "brilliant",
  1294.             "navy blue", "cerise", "chartreuse", "mauve",
  1295.             "lime green", "copper", "sea green", "spiral",
  1296.             "swirly", "blotchy", "fluorescent green",
  1297.             "burnt orange", "indigo", "amber", "tan",
  1298.             "sky blue-pink", "lemon yellow", "off-white",
  1299.             "paisley", "plaid", "argyle", "incandescent"};
  1300.  
  1301. const char *
  1302. hcolor()
  1303. {
  1304.     return hcolors[rn2(SIZE(hcolors))];
  1305. }
  1306.  
  1307. #endif /* OVL2 */
  1308. #ifdef OVL0
  1309.  
  1310. /*ARGSUSED*/
  1311. STATIC_OVL void
  1312. hilite(x, y, let, typ)
  1313. int x, y;
  1314. uchar let, typ;
  1315. {
  1316. #ifdef TEXTCOLOR
  1317.     boolean colorit;
  1318. #endif
  1319.     if (let == ' '
  1320. #if !defined(MSDOS) && !defined(MACOS)
  1321.         || !flags.standout
  1322. #endif
  1323.         ) {
  1324.         /* don't hilite spaces; it's pointless colorwise,
  1325.            and also hilites secret corridors and dark areas. -3. */
  1326.         g_putch(let);
  1327.         return;
  1328.     }
  1329.  
  1330.     if (!typ) {
  1331.         if (let == GOLD_SYM)
  1332.             typ = AT_GLD;
  1333.         else if (index(obj_symbols, (char) let) != NULL
  1334.              || let == S_MIMIC_DEF)
  1335.             /* is an object */
  1336.             typ = AT_OBJ;
  1337.         else if (vism_at(x, y))
  1338.             /* is a monster */
  1339.             typ = AT_MON;
  1340.     }
  1341. #ifdef TEXTCOLOR
  1342. # ifdef REINCARNATION
  1343.     colorit = flags.use_color && dlevel != rogue_level;
  1344. # else
  1345.     colorit = flags.use_color;
  1346. # endif
  1347.     if (colorit) {
  1348.         struct monst *mtmp;
  1349.  
  1350.         switch (typ) {
  1351.         case AT_MON:
  1352.             switch (let) {
  1353.             case S_MIMIC_DEF:
  1354.                 typ = HI_OBJ;
  1355.                 break;
  1356.                 default:
  1357.                 if (u.ux == x && u.uy == y && u.usym == let)
  1358.                 typ = uasmon->mcolor;
  1359.                 else if (mtmp = m_at(x, y))
  1360.                     typ = mtmp->m_ap_type ?
  1361.                     mimic_color(mtmp) :
  1362.                     mtmp->data->mcolor;
  1363.                 else
  1364.                 typ = 0;
  1365.             }
  1366.             break;
  1367.         case AT_OBJ:
  1368.             { struct obj *otmp;
  1369.  
  1370.             if (let == GOLD_SYM)
  1371.             typ = HI_GOLD;
  1372.             else if ((otmp = level.objects[x][y]) && 
  1373.                let == objects[otmp->otyp].oc_olet) {
  1374.             if (otmp->otyp == CORPSE ||
  1375.                 otmp->otyp == DRAGON_SCALE_MAIL)
  1376.                 typ = mons[otmp->corpsenm].mcolor;
  1377.             else
  1378.                 typ = objects[level.objects[x][y]->otyp].oc_color;
  1379.              } else
  1380.             typ = mimic_color(m_at(x, y));
  1381.             }
  1382.             break;
  1383.         case AT_MAP:
  1384.             if ( ((let == POOL_SYM && IS_POOL(levl[x][y].typ))
  1385. #ifdef FOUNTAINS
  1386.             || (let == FOUNTAIN_SYM && IS_FOUNTAIN(levl[x][y].typ))
  1387. #endif
  1388.              ) && hilites[BLUE] != HI)
  1389.  
  1390.             typ = BLUE;
  1391. #ifdef THRONES
  1392.             else if (let == THRONE_SYM && IS_THRONE(levl[x][y].typ)
  1393.                 && hilites[HI_GOLD] != HI)
  1394.             typ = HI_GOLD;
  1395. #endif
  1396.             else if (levl[x][y].typ == ROOM && levl[x][y].icedpool
  1397.                 && hilites[CYAN] != HI)
  1398.             typ = CYAN;
  1399.             else
  1400.             typ = 0;
  1401.             break;
  1402.         case AT_ZAP:
  1403.             typ = HI_ZAP;
  1404.             break;
  1405.         }
  1406.     }
  1407.     if (typ && colorit)
  1408.         xputs(hilites[Hallucination ? rn2(MAXCOLORS) : typ]);
  1409.     else
  1410. #endif
  1411. #ifdef REINCARNATION
  1412.     if (typ == AT_MON && dlevel != rogue_level) revbeg();
  1413. #else
  1414.     if (typ == AT_MON) revbeg();
  1415. #endif
  1416.     g_putch(let);
  1417.  
  1418. #ifdef TEXTCOLOR
  1419.     if (typ && colorit) xputs(HE); else
  1420. #endif
  1421. #ifdef REINCARNATION
  1422.     if (typ == AT_MON && dlevel != rogue_level) m_end();
  1423. #else
  1424.     if (typ == AT_MON) m_end();
  1425. #endif
  1426. }
  1427.  
  1428. #endif /* OVL0 */
  1429. #ifdef OVL2
  1430.  
  1431. /*
  1432.  * find the appropriate symbol for printing a mimic
  1433.  */
  1434.  
  1435. uchar
  1436. mimic_appearance(mon)
  1437. struct monst *mon;
  1438. {
  1439.     switch(mon->m_ap_type) {
  1440.     case M_AP_NOTHING:
  1441.         return mon->data->mlet;
  1442.     case M_AP_FURNITURE:
  1443.         return showsyms[mon->mappearance];
  1444.     case M_AP_OBJECT:
  1445.         return objects[mon->mappearance].oc_olet;
  1446.     case M_AP_MONSTER:
  1447.         return mons[mon->mappearance].mlet;
  1448.     case M_AP_GOLD:
  1449.         return GOLD_SYM;
  1450.     default:
  1451.         impossible("Monster mimicking %d", mon->m_ap_type);
  1452.         return 0;
  1453.     }
  1454. /*NOTREACHED*/
  1455. }
  1456.  
  1457. #ifdef TEXTCOLOR
  1458. /* pick an appropriate color for a mimic imitating an object */
  1459.  
  1460. STATIC_OVL uchar
  1461. mimic_color(mtmp)
  1462. struct monst *mtmp;
  1463. {
  1464.     if (!mtmp)
  1465.         return 0;
  1466.     switch (mtmp->m_ap_type) {
  1467.     case M_AP_NOTHING:
  1468.         return mtmp->data->mcolor;
  1469.     case M_AP_FURNITURE:
  1470. # ifdef FOUNTAINS
  1471.         if (mtmp->mappearance == S_fountain && hilites[BLUE] != HI)
  1472.             return BLUE;
  1473. # endif
  1474.         return 0;
  1475.     case M_AP_OBJECT:
  1476.         return objects[mtmp->mappearance].oc_color;
  1477.     case M_AP_MONSTER:
  1478.         return mons[mtmp->mappearance].mcolor;
  1479.     case M_AP_GOLD:
  1480.         return HI_GOLD;
  1481.     default:
  1482.         return 0;
  1483.     }
  1484. }
  1485. #endif
  1486.  
  1487. #endif /* OVL2 */
  1488.